const fs = require('fs');
const Promise = require('bluebird');
const wechat = require('wechat');
const WechatAPI = require('wechat-api');
const OAuth = require('wechat-oauth');
const emoji = require('node-emoji');

module.exports = {
    newInstance: function (storage, wechatConfig) {
        let {models: {Users}, cache: {settings}, qiniu, redis} = storage;
        let {shop_web_appid, shop_web_secret} = wechatConfig;
        let wechatApi = {};

        /**
         * 微信Shop Web
         */
        if (shop_web_appid && shop_web_secret) {
            /**
             * 配置
             */
            let shopWebConfig = {
                appid: shop_web_appid,
                appId: shop_web_appid,
                secret: shop_web_secret,
                token: wechatConfig.shop_web_token,
                encodingAESKey: wechatConfig.shop_web_encodingAESKey,
                mchId: wechatConfig.shop_web_mchId,
                partnerKey: wechatConfig.shop_web_partnerKey,
                spbill_create_ip: wechatConfig.spbill_create_ip || '8.8.8.8',
                debug: wechatConfig.shop_web_debug,
                jsApiList: wechatConfig.shop_web_jsApiList || ["checkJsApi", "getLocation", "onMenuShareTimeline", "onMenuShareAppMessage", "onMenuShareQQ", "onMenuShareWeibo", "onMenuShareQZone"],
                notifyUrl: wechatConfig.notifyUrl
            };

            /**
             * 公众号API
             */
            wechatApi.shopWebApi = new WechatAPI(shop_web_appid, shop_web_secret, function (callback) {
                redis.globalClient.get("wechat_shop_web_access_token", function (err, reply) {
                    if (err) {
                        return callback(err);
                    }
                    callback(null, reply ? JSON.parse(reply) : null);
                });
            }, function (token, callback) {
                redis.globalClient.set('wechat_shop_web_access_token', JSON.stringify(token));
                callback(null);
            });

            /**
             * 微信 ticketToken
             */
            wechatApi.shopWebApi.registerTicketHandle(function (type, callback) {
                redis.globalClient.get(type + '_wechat_shop_web_ticketToken', function (err, reply) {
                    if (err) {
                        console.error(type + '_wechat_shop_web_ticketToken');
                        return callback(err);
                    }
                    callback(null, reply ? JSON.parse(reply) : null);
                });
            }, function (type, ticketToken, callback) {
                redis.globalClient.set(type + '_wechat_shop_web_ticketToken', JSON.stringify(ticketToken));
                callback(null);
            });

            /**
             * 认证
             */
            wechatApi.shopWebOauth = new OAuth(shop_web_appid, shop_web_secret, function (openid, callback) {
                redis.globalClient.get(openid + ":wechat_shop_web_access_token", function (err, reply) {
                    if (err) {
                        return callback(err);
                    }
                    callback(null, reply ? JSON.parse(reply) : null);
                });
            }, function (openid, token, callback) {
                redis.globalClient.set(openid + ':wechat_shop_web_access_token', JSON.stringify(token));
                callback(null);
            });


            /**
             * 消息处理
             */
            let text = require('./text')(settings, storage);
            let events = require('./events')(settings, storage);
            let clicks = require('./clicks')(settings, storage);

            wechatApi.wechatMiddleware = wechat(shopWebConfig).text(function (message, req, res, next) {
                return text.handle(message, req, res, next);
            }).event(function (message, req, res, next) {
                try {
                    let event = message.Event.toLowerCase();
                    if (events[event]) {
                        return events[event](message, req, res, next);
                    }
                    if (event == 'click') {
                        if (clicks[message.EventKey]) {
                            clicks[message.EventKey](message, req, res, next);
                        } else {
                            if (clicks['others']) {
                                clicks['others'](message, req, res, next);
                            }
                        }
                    }
                } catch (err) {
                    console.error('\n', err.stack || err.message);
                }
            }).middlewarify();
        }

        /**
         * 初始化用户通过微信
         */
        wechatApi.getUserByOpenid = function (openid, body, subscribe) {
            return new Promise(function (resolve) {
                return Users.findOne({where: {openid: openid}}).then(function (user) {
                    if (user) {
                        if (subscribe && !user.subscribe) {
                            Users.update({subscribe: 1}, {where: {id: user.id}});
                        }
                        return resolve({
                            success: true,
                            data: user,
                            new: false
                        });
                    }
                    wechatApi.shopWebApi.getUser(openid, function (err, result) {
                        if (err) {
                            console.error('\n', err.stack || err.message);
                            return resolve({success: false});
                        }
                        if (!body) {
                            body = {};
                        }
                        body.openid = result.openid;
                        if (result.unionid) {
                            body.unionid = result.unionid;
                        }
                        if (result.nickname) {
                            body.nickname = emoji.strip(result.nickname || '');
                        }
                        if (result.headimgurl) {
                            body.image = result.headimgurl;
                        }
                        if (!(result.subscribe === undefined)) {
                            body.subscribe = result.subscribe;
                        }
                        if (!(result.sex === undefined)) {
                            body.sex = result.sex;
                        }
                        body.ext_data = emoji.strip(JSON.stringify(result));

                        return Users.registerV2(body).then(function (r) {
                            if (!r.success) {
                                return r;
                            }
                            let user = r.data;
                            if (result.headimgurl) {
                                qiniu.portraitUpload(storage.config.qiniu, result.headimgurl).then(function (result) {
                                    if (result.success) {
                                        Users.update({image: result.image}, {where: {id: user.id}});
                                    }
                                });
                            }
                            r.new = true;
                            return resolve(r);
                        });
                    });
                });
            });
        }
        wechatApi.getUserByOauth = function (oauthData, body) {
            return new Promise(function (resolve) {
                return Users.findOne({where: {openid: oauthData.openid}}).then(function (user) {
                    if (user) {
                        return resolve({
                            success: true,
                            data: user,
                            new: false
                        });
                    }
                    wechatApi.shopWebOauth._getUser({openid: oauthData.openid}, oauthData.access_token, function (err, result) {
                        if (err) {
                            console.error('\n', err.stack || err.message);
                            return resolve({success: false});
                        }
                        if (!body) {
                            body = {};
                        }
                        body.openid = result.openid;
                        if (result.unionid) {
                            body.unionid = result.unionid;
                        }
                        if (result.nickname) {
                            body.nickname = emoji.strip(result.nickname || '');
                        }
                        if (result.headimgurl) {
                            body.image = result.headimgurl;
                        }
                        if (!(result.subscribe === undefined)) {
                            body.subscribe = result.subscribe;
                        }
                        if (!(result.sex === undefined)) {
                            body.sex = result.sex;
                        }
                        body.ext_data = emoji.strip(JSON.stringify(result));

                        return Users.registerV2(body).then(function (r) {
                            if (!r.success) {
                                return r;
                            }
                            let user = r.data;
                            if (result.headimgurl) {
                                qiniu.portraitUpload(storage.config.qiniu, result.headimgurl).then(function (result) {
                                    if (result.success) {
                                        Users.update({image: result.image}, {where: {id: user.id}});
                                    }
                                });
                            }
                            r.new = true;
                            return resolve(r);
                        });
                    });
                });
            });
        };

        return wechatApi;
    }
};